////////////////////////////////////////////////////////////////////////////////
//
//  ADOBE SYSTEMS INCORPORATED
//  Copyright 2003-2007 Adobe Systems Incorporated
//  All Rights Reserved.
//
//  NOTICE: Adobe permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////

package mx.managers
{

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.EventPhase;
import flash.events.FocusEvent;
import flash.events.IEventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.ApplicationDomain;
import flash.system.Capabilities;
import flash.system.Security;
import flash.text.Font;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Timer;
import flash.utils.getQualifiedClassName;

import mx.core.FlexSprite;
import mx.core.IChildList;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IInvalidating;
import mx.core.IRawChildrenContainer;
import mx.core.IUIComponent;
import mx.core.RSLData;
import mx.core.RSLItem;
import mx.core.Singleton;
import mx.core.mx_internal;
import mx.events.DynamicEvent;
import mx.events.FlexEvent;
import mx.events.RSLEvent;
import mx.events.Request;
import mx.events.ResizeEvent;
import mx.events.SandboxMouseEvent;
import mx.preloaders.Preloader;
import mx.utils.DensityUtil;
import mx.utils.LoaderUtil;

// NOTE: Minimize the non-Flash classes you import here.
// Any dependencies of SystemManager have to load in frame 1,
// before the preloader, or anything else, can be displayed.

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the application has finished initializing
 *
 *  @eventType mx.events.FlexEvent.APPLICATION_COMPLETE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="applicationComplete", type="mx.events.FlexEvent")]

/**
 *  Dispatched every 100 milliseconds when there has been no keyboard
 *  or mouse activity for 1 second.
 *
 *  @eventType mx.events.FlexEvent.IDLE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="idle", type="mx.events.FlexEvent")]

/**
 *  Dispatched when the Stage is resized.
 *
 *  @eventType flash.events.Event.RESIZE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="resize", type="flash.events.Event")]

/**
 *  The SystemManager class manages an application window.
 *  Every application that runs on the desktop or in a browser
 *  has an area where the visuals of the application are 
 *  displayed.  
 *  It may be a window in the operating system
 *  or an area within the browser.  That area is an application window
 *  and different from an instance of <code>mx.core.Application</code>, which
 *  is the main, or top-level, window within an application.
 *
 *  <p>Every application has a SystemManager.  
 *  The SystemManager sends an event if
 *  the size of the application window changes (you cannot change it from
 *  within the application, but only through interaction with the operating
 *  system window or browser).  It parents all displayable things within the
 *  application like the main mx.core.Application instance and all popups, 
 *  tooltips, cursors, and so on.  Any object parented by the SystemManager is
 *  considered to be a top-level window, even tooltips and cursors.</p>
 *
 *  <p>The SystemManager also switches focus between top-level windows if there 
 *  are more than one IFocusManagerContainer displayed and users are interacting
 *  with components within the IFocusManagerContainers.  </p>
 *
 *  <p>All keyboard and mouse activity that is not expressly trapped is seen by
 *  the SystemManager, making it a good place to monitor activity should you need
 *  to do so.</p>
 *
 *  <p>If an application is loaded into another application, a SystemManager
 *  will still be created, but will not manage an application window,
 *  depending on security and domain rules.
 *  Instead, it will be the <code>content</code> of the <code>Loader</code> 
 *  that loaded it and simply serve as the parent of the sub-application</p>
 *
 *  <p>The SystemManager maintains multiple lists of children, one each for tooltips, cursors,
 *  popup windows.  This is how it ensures that popup windows "float" above the main
 *  application windows and that tooltips "float" above that and cursors above that.
 *  If you simply examine the <code>numChildren</code> property or 
 *  call the <code>getChildAt()</code> method on the SystemManager, you are accessing
 *  the main application window and any other windows that aren't popped up.  To get the list
 *  of all windows, including popups, tooltips and cursors, use 
 *  the <code>rawChildren</code> property.</p>
 *
 *  <p>The SystemManager is the first display class created within an application.
 *  It is responsible for creating an <code>mx.preloaders.Preloader</code> that displays and
 *  <code>mx.preloaders.SparkDownloadProgressBar</code> while the application finishes loading,
 *  then creates the <code>mx.core.Application</code> instance.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class SystemManager extends MovieClip
	implements IChildList, IFlexDisplayObject,
	IFlexModuleFactory, ISystemManager
{
//	include "../core/Version.as";
	
	//--------------------------------------------------------------------------
	//
	//  Class constants
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  The number of milliseconds that must pass without any user activity
	 *  before SystemManager starts dispatching 'idle' events.
	 */
	private static const IDLE_THRESHOLD:Number = 1000;
	
	/**
	 *  @private
	 *  The number of milliseconds between each 'idle' event.
	 */
	private static const IDLE_INTERVAL:Number = 100;
	
	//--------------------------------------------------------------------------
	//
	//  Class variables
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  An array of SystemManager instances loaded as child app domains
	 */
	mx_internal static var allSystemManagers:Dictionary = new Dictionary(true);
	
	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  Constructor.
	 *
	 *  <p>This is the starting point for all Flex applications.
	 *  This class is set to be the root class of a Flex SWF file.
	 *  Flash Player instantiates an instance of this class,
	 *  causing this constructor to be called.</p>
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function SystemManager()
	{
//		CONFIG::performanceInstrumentation
//		{
//			var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
//			perfUtil.startSampling("Application Startup", true /*absoluteTime*/);
//			perfUtil.markTime("SystemManager c-tor");
//		}
		
		super();
		
		// Loaded SWFs don't get a stage right away
		// and shouldn't override the main SWF's setting anyway.
		if (stage)
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.HIGH;
		}
		
		// If we don't have a stage then we are not top-level,
		// unless there are no other top-level managers, in which
		// case we got loaded by a non-Flex shell or are sandboxed.
		if (SystemManagerGlobals.topLevelSystemManagers.length > 0 && !stage)
			topLevel = false;
		
		if (!stage)
			isStageRoot = false;
		
		if (topLevel)
			SystemManagerGlobals.topLevelSystemManagers.push(this);
		
		// Make sure to stop the playhead on the current frame.
		stop();
		
		// Listen for the last frame (param is 0-indexed) to be executed.
		//addFrameScript(totalFrames - 1, frameEndHandler);
		
		if (root && root.loaderInfo)
			root.loaderInfo.addEventListener(Event.INIT, initHandler);
		
	}
	
	
	
	/**
	 *  @private
	 */
	private function deferredNextFrame():void
	{
		if (currentFrame + 1 > totalFrames)
			return;
		
		if (currentFrame + 1 <= framesLoaded)
		{
//			CONFIG::performanceInstrumentation
//			{
//				var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
//				perfUtil.markTime("SystemManager.nextFrame().start");
//			}
			
			nextFrame();
			
//			CONFIG::performanceInstrumentation
//			{
//				perfUtil.markTime("SystemManager.nextFrame().end");
//			}
		}
		else
		{
			// Next frame isn't baked yet, so we'll check back...
			nextFrameTimer = new Timer(100);
			nextFrameTimer.addEventListener(TimerEvent.TIMER,
				nextFrameTimerHandler);
			nextFrameTimer.start();
		}
	}
	
	//--------------------------------------------------------------------------
	//
	//  Variables
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  Whether we are in the top-level list or not;
	 *  top-level means we are the highest level SystemManager
	 *  for this stage.
	 */
	mx_internal var topLevel:Boolean = true;
	
	/**
	 *  @private
	 * 
	 * true if redipatching a resize event.
	 */
	private var isDispatchingResizeEvent:Boolean;
	
	/**
	 *  @private
	 *  Whether we are the stage root or not.
	 *  We are only the stage root if we were the root
	 *  of the first SWF that got loaded by the player.
	 *  Otherwise we could be top level but not stage root
	 *  if we are loaded by some other non-Flex shell
	 *  or are sandboxed.
	 */
	mx_internal var isStageRoot:Boolean = true;
	
	/**
	 *  @private
	 *  Whether we are the first SWF loaded into a bootstrap
	 *  and therefore, the topLevelRoot
	 */
	mx_internal var isBootstrapRoot:Boolean = false;
	
	/**
	 *  @private
	 *  If we're not top level, then we delegate many things
	 *  to the top level SystemManager.
	 */
	private var _topLevelSystemManager:ISystemManager;
	
	/**
	 *  @private
	 *  The childAdded/removed code
	 */
	mx_internal var childManager:ISystemManagerChildManager;
	
	/**
	 * cached value of the stage.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	private var _stage:Stage;
	
	/**
	 *  Depth of this object in the containment hierarchy.
	 *  This number is used by the measurement and layout code.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	mx_internal var nestLevel:int = 0;
	
	/**
	 *  @private
	 *  A reference to the preloader.
	 */
	mx_internal var preloader:Preloader;
	
	/**
	 *  @private
	 *  The mouseCatcher is the 0th child of the SystemManager,
	 *  behind the application, which is child 1.
	 *  It is the same size as the stage and is filled with
	 *  transparent pixels; i.e., they've been drawn, but with alpha 0.
	 *
	 *  Its purpose is to make every part of the stage
	 *  able to detect the mouse.
	 *  For example, a Button puts a mouseUp handler on the SystemManager
	 *  in order to capture mouseUp events that occur outside the Button.
	 *  But if the children of the SystemManager don't have "drawn-on"
	 *  pixels everywhere, the player won't dispatch the mouseUp.
	 *  We can't simply fill the SystemManager itself with
	 *  transparent pixels, because the player's pixel detection
	 *  logic doesn't look at pixels drawn into the root DisplayObject.
	 *
	 *  Here is an example of what would happen without the mouseCatcher:
	 *  Run a fixed-size Application (e.g. width="600" height="600")
	 *  in the standalone player. Make the player window larger
	 *  to reveal part of the stage. Press a Button, drag off it
	 *  into the stage area, and release the mouse button.
	 *  Without the mouseCatcher, the Button wouldn't return to its "up" state.
	 */
	private var mouseCatcher:Sprite;
	
	/**
	 *  @private
	 *  The top level window.
	 */
	mx_internal var topLevelWindow:IUIComponent;
	
	/**
	 *  @private
	 *  Number of frames since the last mouse or key activity.
	 */
	mx_internal var idleCounter:int = 0;
	
	/**
	 *  @private
	 *  The Timer used to determine when to dispatch idle events.
	 */
	private var idleTimer:Timer;
	
	/**
	 *  @private
	 *  A timer used when it is necessary to wait before incrementing the frame
	 */
	private var nextFrameTimer:Timer = null;
	
	/**
	 *  @private
	 *  Track which frame was last processed
	 */
	private var lastFrame:int;
	
	/**
	 *  @private
	 *  A boolean as to whether we've seen COMPLETE event from preloader
	 */
	private var readyForKickOff:Boolean;
	
	/**
	 *  @private
	 * 
	 *  This variable exists only to provide a reference to this 
	 *  app's resource bundles. This application is opting
	 *  into referencing its own resource bundles so the
	 *  ResourceManager does not need to do it. This 
	 *  arrangement keeps the ResourceManager from pinning
	 *  the application in memory. 
	 * 
	 *  If this is the main app, then this variable will be null.
	 *  If this is a sub-app then ResourceManagerImpl set 
	 *  this variable to the apps resource bundles. This variable 
	 *  is public so it is visible to ResourceManagerImpl but starts
	 *  with an underscore to hint that it is an implementation detail 
	 *  and should not be relied on. 
	 */
	public var _resourceBundles:Array;
	
	/**
	 *  @private
	 *  Array of RSLData objects that represent the list of RSLs this
	 *  module factory is loading. Each element of the Array is an 
	 *  Array of RSLData.
	 */ 
	private var rslDataList:Array
	
	//--------------------------------------------------------------------------
	//
	//  Overridden properties: DisplayObject
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	//  height
	//----------------------------------
	
	/**
	 *  @private
	 */
	private var _height:Number;
	
	/**
	 *  The height of this object.  For the SystemManager
	 *  this should always be the width of the stage unless the application was loaded
	 *  into another application.  If the application was not loaded
	 *  into another application, setting this value has no effect.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	override public function get height():Number
	{
		return _height;
	}
	
	//----------------------------------
	//  stage
	//----------------------------------
	
	/**
	 *  @private
	 *  get the main stage if we're loaded into another swf in the same sandbox
	 */
	override public function get stage():Stage
	{
		if (_stage)
			return _stage;
		
		var s:Stage = super.stage;
		if (s)
		{
			_stage = s;
			return s;
		}
		
		if (!topLevel && _topLevelSystemManager)
		{
			_stage = _topLevelSystemManager.stage; 
			return _stage;
		}
		
		// Case for version skew, we are a top level system manager, but
		// a child of the top level root system manager and we have access 
		// to the stage. 
		if (!isStageRoot && topLevel)
		{
			var root:DisplayObject = getTopLevelRoot();
			if (root)
			{
				_stage = root.stage;
				return _stage;
			}
		}
		
		return null;
	}
	
	//----------------------------------
	//  width
	//----------------------------------
	
	/**
	 *  @private
	 */
	private var _width:Number;
	
	/**
	 *  The width of this object.  For the SystemManager
	 *  this should always be the width of the stage unless the application was loaded
	 *  into another application.  If the application was not loaded
	 *  into another application, setting this value will have no effect.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	override public function get width():Number
	{
		return _width;
	}
	
	//--------------------------------------------------------------------------
	//
	//  Overridden properties: DisplayObjectContainer
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	//  numChildren
	//----------------------------------
	
	/**
	 *  The number of non-floating windows.  This is the main application window
	 *  plus any other windows added to the SystemManager that are not popups,
	 *  tooltips or cursors.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	override public function get numChildren():int
	{
		return noTopMostIndex - applicationIndex;
	}
	
	//--------------------------------------------------------------------------
	//
	//  Properties
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	//  allowDomainsInNewRSLs
	//----------------------------------
	
	/**
	 *  @private
	 */ 
	private var _allowDomainsInNewRSLs:Boolean = true;
	
	/**
	 *  @inheritDoc
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion Flex 4.5
	 */   
	public function get allowDomainsInNewRSLs():Boolean
	{
		return _allowDomainsInNewRSLs;
	}
	
	/**
	 *  @private
	 */ 
	public function set allowDomainsInNewRSLs(value:Boolean):void
	{
		_allowDomainsInNewRSLs = value;
	}
	
	//----------------------------------
	//  allowInsecureDomainsInNewRSLs
	//----------------------------------
	
	/**
	 *  @private
	 */ 
	private var _allowInsecureDomainsInNewRSLs:Boolean = true;
	
	/**
	 *  @inheritDoc
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion Flex 4.5
	 */   
	public function get allowInsecureDomainsInNewRSLs():Boolean
	{
		return _allowInsecureDomainsInNewRSLs;
	}
	
	/**
	 *  @private
	 */ 
	public function set allowInsecureDomainsInNewRSLs(value:Boolean):void
	{
		_allowInsecureDomainsInNewRSLs = value;
	}
	
	//----------------------------------
	//  application
	//----------------------------------
	
	/**
	 *  The application parented by this SystemManager.
	 *  SystemManagers create an instance of an Application
	 *  even if they are loaded into another Application.
	 *  Thus, this may not match mx.core.Application.application
	 *  if the SWF has been loaded into another application.
	 *  <p>Note that this property is not typed as mx.core.Application
	 *  because of load-time performance considerations
	 *  but can be coerced into an mx.core.Application.</p>
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get application():IUIComponent
	{
		return IUIComponent(_document);
	}
	
	//----------------------------------
	//  applicationIndex
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the applicationIndex property.
	 */
	private var _applicationIndex:int = 1;
	
	/**
	 *  @private
	 *  The index of the main mx.core.Application window, which is
	 *  effectively its z-order.
	 */
	mx_internal function get applicationIndex():int
	{
		return _applicationIndex;
	}
	
	/**
	 *  @private
	 */
	mx_internal function set applicationIndex(value:int):void
	{
		_applicationIndex = value;
	}
	
	
	//----------------------------------
	//  cursorChildren
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the cursorChildren property.
	 */
	private var _cursorChildren:SystemChildrenList;
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get cursorChildren():IChildList
	{
		if (!topLevel)
			return _topLevelSystemManager.cursorChildren;
		
		if (!_cursorChildren)
		{
			_cursorChildren = new SystemChildrenList(this,
				new QName(mx_internal, "toolTipIndex"),
				new QName(mx_internal, "cursorIndex"));
		}
		
		return _cursorChildren;
	}
	
	//----------------------------------
	//  cursorIndex
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the toolTipIndex property.
	 */
	private var _cursorIndex:int = 0;
	
	/**
	 *  @private
	 *  The index of the highest child that is a cursor.
	 */
	mx_internal function get cursorIndex():int
	{
		return _cursorIndex;
	}
	
	/**
	 *  @private
	 */
	mx_internal function set cursorIndex(value:int):void
	{
		var delta:int = value - _cursorIndex;
		_cursorIndex = value;
	}
	
	//----------------------------------
	//  densityScale
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the densityScale property 
	 */
	private var _densityScale:Number = NaN;
	
	/**
	 *  The density scale factor of the application.
	 * 
	 *  When density scaling is enabled, Flex applies a scale factor based on
	 *  the application author density and the density of the current device
	 *  that Flex is running on. 
	 * 
	 *  Returns 1.0 when there is no scaling.
	 * 
	 *  @see spark.components.Application#applicationDPI
	 *  @see mx.core.DensityUtil
	 * 
	 *  @private
	 */
	mx_internal function get densityScale():Number
	{
		if (isNaN(_densityScale))
		{    
			var applicationDPI:Number = info()["applicationDPI"];
			var runtimeDPI:Number = DensityUtil.getRuntimeDPI();
			_densityScale = DensityUtil.getDPIScale(applicationDPI, runtimeDPI);
			if (isNaN(_densityScale))
				_densityScale = 1;
		}
		
		return _densityScale;
	}
	
	//----------------------------------
	//  document
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the document property.
	 */
	private var _document:Object;
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get document():Object
	{
		return _document;
	}
	
	/**
	 *  @private
	 */
	public function set document(value:Object):void
	{
		_document = value;
	}
	
	//----------------------------------
	//  embeddedFontList
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the fontList property.
	 */
	private var _fontList:Object = null;
	
	/**
	 *  A table of embedded fonts in this application.  The 
	 *  object is a table indexed by the font name.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get embeddedFontList():Object
	{
		if (_fontList == null)
		{
			_fontList = {};
			
			var o:Object = info()["fonts"];
			
			var p:String;
			
			for (p in o)
			{
				_fontList[p] = o[p];
			}
			
			// Top level systemManager may not be defined if SWF is loaded
			// as a background image in download progress bar.
			if (!topLevel && _topLevelSystemManager)                   
			{
				var fl:Object = _topLevelSystemManager.embeddedFontList;
				for (p in fl)
				{
					_fontList[p] = fl[p];
				}
			}
		}
		
		return _fontList;
	}
	
	//----------------------------------
	//  explicitHeight
	//----------------------------------
	
	/**
	 *  @private
	 */
	private var _explicitHeight:Number;
	
	/**
	 *  The explicit width of this object.  For the SystemManager
	 *  this should always be NaN unless the application was loaded
	 *  into another application.  If the application was not loaded
	 *  into another application, setting this value has no effect.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get explicitHeight():Number
	{
		return _explicitHeight;
	}
	
	/**
	 *  @private
	 */
	public function set explicitHeight(value:Number):void
	{
		_explicitHeight = value;
	}
	
	//----------------------------------
	//  explicitWidth
	//----------------------------------
	
	/**
	 *  @private
	 */
	private var _explicitWidth:Number;
	
	/**
	 *  The explicit width of this object.  For the SystemManager
	 *  this should always be NaN unless the application was loaded
	 *  into another application.  If the application was not loaded
	 *  into another application, setting this value has no effect.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get explicitWidth():Number
	{
		return _explicitWidth;
	}
	
	/**
	 *  @private
	 */
	public function set explicitWidth(value:Number):void
	{
		_explicitWidth = value;
	}
	
	//----------------------------------
	//  focusPane
	//----------------------------------
	
	/**
	 *  @private
	 */
	private var _focusPane:Sprite;
	
	/**
	 *  @copy mx.core.UIComponent#focusPane
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get focusPane():Sprite
	{
		return _focusPane;
	}
	
	/**
	 *  @private
	 */
	public function set focusPane(value:Sprite):void
	{
		if (value)
		{
			addChild(value);
			
			value.x = 0;
			value.y = 0;
			value.scrollRect = null;
			
			_focusPane = value;
		}
		else
		{
			removeChild(_focusPane);
			
			_focusPane = null;
		}
	}
	
	//----------------------------------
	//  isProxy
	//----------------------------------
	
	/**
	 *  True if SystemManager is a proxy and not a root class
	 */
	public function get isProxy():Boolean
	{
		return false;
	}
	
	//----------------------------------
	//  measuredHeight
	//----------------------------------
	
	/**
	 *  The measuredHeight is the explicit or measuredHeight of 
	 *  the main mx.core.Application window
	 *  or the starting height of the SWF if the main window 
	 *  has not yet been created or does not exist.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get measuredHeight():Number
	{
		return topLevelWindow ?
			topLevelWindow.getExplicitOrMeasuredHeight() :
			loaderInfo.height;
	}
	
	//----------------------------------
	//  measuredWidth
	//----------------------------------
	
	/**
	 *  The measuredWidth is the explicit or measuredWidth of 
	 *  the main mx.core.Application window,
	 *  or the starting width of the SWF if the main window 
	 *  has not yet been created or does not exist.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get measuredWidth():Number
	{
		return topLevelWindow ?
			topLevelWindow.getExplicitOrMeasuredWidth() :
			loaderInfo.width;
	}
	
	//----------------------------------
	//  noTopMostIndex
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the noTopMostIndex property.
	 */
	private var _noTopMostIndex:int = 0;
	
	/**
	 *  @private
	 *  The index of the highest child that isn't a topmost/popup window
	 */
	mx_internal function get noTopMostIndex():int
	{
		return _noTopMostIndex;
	}
	
	/**
	 *  @private
	 */
	mx_internal function set noTopMostIndex(value:int):void
	{
		var delta:int = value - _noTopMostIndex;
		_noTopMostIndex = value;
		topMostIndex += delta;
	}
	
	//----------------------------------
	//  $numChildren
	//----------------------------------
	
	/**
	 *  @private
	 *  This property allows access to the Player's native implementation
	 *  of the numChildren property, which can be useful since components
	 *  can override numChildren and thereby hide the native implementation.
	 *  Note that this "base property" is final and cannot be overridden,
	 *  so you can count on it to reflect what is happening at the player level.
	 */
	mx_internal final function get $numChildren():int
	{
		return super.numChildren;
	}
	
	//----------------------------------
	//  numModalWindows
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the numModalWindows property.
	 */
	private var _numModalWindows:int = 0;
	
	/**
	 *  The number of modal windows.  Modal windows don't allow
	 *  clicking in another windows which would normally
	 *  activate the FocusManager in that window.  The PopUpManager
	 *  modifies this count as it creates and destroys modal windows.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get numModalWindows():int
	{
		return _numModalWindows;
	}
	
	/**
	 *  @private
	 */
	public function set numModalWindows(value:int):void
	{
		_numModalWindows = value;
	}
	
	//----------------------------------
	//  preloadedRSLs
	//----------------------------------
	
	/**
	 *  @inheritDoc 
	 *  
	 */
	public function  get preloadedRSLs():Dictionary
	{
		// Overridden by compiler generate code.
		return null;                
	}
	
	/**
	 *  @inheritDoc 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 4.5
	 */ 
	public function addPreloadedRSL(loaderInfo:LoaderInfo, rsl:Vector.<RSLData>):void
	{
		preloadedRSLs[loaderInfo] = rsl;
		if (hasEventListener(RSLEvent.RSL_ADD_PRELOADED))
		{
			var rslEvent:RSLEvent = new RSLEvent(RSLEvent.RSL_ADD_PRELOADED);
			rslEvent.loaderInfo = loaderInfo;
			dispatchEvent(rslEvent);
		}
		
	}
	
	//----------------------------------
	//  preloaderBackgroundAlpha
	//----------------------------------
	
	/**
	 *  The background alpha used by the child of the preloader.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get preloaderBackgroundAlpha():Number
	{
		return info()["backgroundAlpha"];
	}
	
	//----------------------------------
	//  preloaderBackgroundColor
	//----------------------------------
	
	/**
	 *  The background color used by the child of the preloader.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get preloaderBackgroundColor():uint
	{
		var value:* = info()["backgroundColor"];
		if (value == undefined)
			return 0xFFFFFFFF;
		else
			return value;
	}
	
	//----------------------------------
	//  preloaderBackgroundImage
	//----------------------------------
	
	/**
	 *  The background color used by the child of the preloader.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get preloaderBackgroundImage():Object
	{
		return info()["backgroundImage"];
	}
	
	//----------------------------------
	//  preloaderBackgroundSize
	//----------------------------------
	
	/**
	 *  The background size used by the child of the preloader.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get preloaderBackgroundSize():String
	{
		return info()["backgroundSize"];
	}
	
	//----------------------------------
	//  popUpChildren
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the popUpChildren property.
	 */
	private var _popUpChildren:SystemChildrenList;
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get popUpChildren():IChildList
	{
		if (!topLevel)
			return _topLevelSystemManager.popUpChildren;
		
		if (!_popUpChildren)
		{
			_popUpChildren = new SystemChildrenList(this,
				new QName(mx_internal, "noTopMostIndex"),
				new QName(mx_internal, "topMostIndex"));
		}
		
		return _popUpChildren;
	}
	
	//----------------------------------
	//  rawChildren
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the rawChildren property.
	 */
	private var _rawChildren:SystemRawChildrenList;
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get rawChildren():IChildList
	{
		//if (!topLevel)
		//  return _topLevelSystemManager.rawChildren;
		
		if (!_rawChildren)
			_rawChildren = new SystemRawChildrenList(this);
		
		return _rawChildren;
	}
	
	//--------------------------------------------------------------------------
	//  screen
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  Storage for the screen property.
	 */
	mx_internal var _screen:Rectangle;
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get screen():Rectangle
	{
		if (!_screen)
			Stage_resizeHandler();
		
		if (!isStageRoot)
		{
			Stage_resizeHandler();
		}
		return _screen;
	}
	
	//----------------------------------
	//  toolTipChildren
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the toolTipChildren property.
	 */
	private var _toolTipChildren:SystemChildrenList;
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get toolTipChildren():IChildList
	{
		if (!topLevel)
			return _topLevelSystemManager.toolTipChildren;
		
		if (!_toolTipChildren)
		{
			_toolTipChildren = new SystemChildrenList(this,
				new QName(mx_internal, "topMostIndex"),
				new QName(mx_internal, "toolTipIndex"));
		}
		
		return _toolTipChildren;
	}
	
	//----------------------------------
	//  toolTipIndex
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the toolTipIndex property.
	 */
	private var _toolTipIndex:int = 0;
	
	/**
	 *  @private
	 *  The index of the highest child that is a tooltip
	 */
	mx_internal function get toolTipIndex():int
	{
		return _toolTipIndex;
	}
	
	/**
	 *  @private
	 */
	mx_internal function set toolTipIndex(value:int):void
	{
		var delta:int = value - _toolTipIndex;
		_toolTipIndex = value;
		cursorIndex += delta;
	}
	
	//----------------------------------
	//  topLevelSystemManager
	//----------------------------------
	
	/**
	 *  Returns the SystemManager responsible for the application window.  This will be
	 *  the same SystemManager unless this application has been loaded into another
	 *  application.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get topLevelSystemManager():ISystemManager
	{
		if (topLevel)
			return this;
		
		return _topLevelSystemManager;
	}
	
	//----------------------------------
	//  topMostIndex
	//----------------------------------
	
	/**
	 *  @private
	 *  Storage for the topMostIndex property.
	 */
	private var _topMostIndex:int = 0;
	
	/**
	 *  @private
	 *  The index of the highest child that is a topmost/popup window
	 */
	mx_internal function get topMostIndex():int
	{
		return _topMostIndex;
	}
	
	mx_internal function set topMostIndex(value:int):void
	{
		var delta:int = value - _topMostIndex;
		_topMostIndex = value;
		toolTipIndex += delta;
	}
	
	
	//--------------------------------------------------------------------------
	//
	//  Overridden methods: EventDispatcher
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  allows marshal implementation to add events
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	mx_internal final function $addEventListener(type:String, listener:Function,
												 useCapture:Boolean = false,
												 priority:int = 0,
												 useWeakReference:Boolean = false):void
	{   
		super.addEventListener(type, listener, useCapture, priority, useWeakReference);
	}
	
	/**
	 * @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */    
	public function get childAllowsParent():Boolean
	{
		try
		{
			return loaderInfo.childAllowsParent;
		}
		catch (error:Error)
		{
			//Error #2099: The loading object is not sufficiently loaded to provide this information.
		}
		
		return false;   // assume the worst
	}
	
	/**
	 *  @copy mx.core.ISWFBridgeProvider#parentAllowsChild
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */    
	public function get parentAllowsChild():Boolean
	{
		try
		{
			return loaderInfo.parentAllowsChild;
		}
		catch (error:Error)
		{
			//Error #2099: The loading object is not sufficiently loaded to provide this information.
		}
		
		return false;   // assume the worst
	}
	
	/**
	 * @private
	 *  Only create idle events if someone is listening.
	 */
	override public function addEventListener(type:String, listener:Function,
											  useCapture:Boolean = false,
											  priority:int = 0,
											  useWeakReference:Boolean = false):void
	{
		if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN 
			|| type == Event.ACTIVATE || type == Event.DEACTIVATE)
		{
			// also listen to stage if allowed
			try
			{
				if (stage)
				{
					// Use weak listener because we don't always know when we
					// no longer need this listener
					stage.addEventListener(type, stageEventHandler, false, 0, true);
				}
			}
			catch (error:SecurityError)
			{
			}
		}
		
		if (hasEventListener("addEventListener"))
		{
			var request:DynamicEvent = new DynamicEvent("addEventListener", false, true);
			request.eventType = type;
			request.listener = listener;
			request.useCapture = useCapture;
			request.priority = priority;
			request.useWeakReference = useWeakReference;
			if (!dispatchEvent(request))
				return;
		}
		
		if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE)
		{
			// If someone wants this event, also listen for mouseLeave.
			// Use weak listener because we don't always know when we
			// no longer need this listener
			try
			{
				if (stage)
				{
					stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
				}
				else
				{
					super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
				}
			}
			catch (error:SecurityError)
			{
				super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
			}
		}
		
		// These two events will dispatched to applications in sandboxes.
		if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME)
		{
			if (type == FlexEvent.RENDER)
				type = Event.RENDER;
			else
				type = Event.ENTER_FRAME;
			
			try
			{
				if (stage)
					stage.addEventListener(type, listener, useCapture, priority, useWeakReference);
				else
					super.addEventListener(type, listener, useCapture, priority, useWeakReference);
			}
			catch (error:SecurityError)
			{
				super.addEventListener(type, listener, useCapture, priority, useWeakReference);
			}
			
			if (stage && type == Event.RENDER)
				stage.invalidate();
			
			return;
		}
		
		// When the first listener registers for 'idle' events,
		// create a Timer that will fire every IDLE_INTERVAL.
		if (type == FlexEvent.IDLE && !idleTimer)
		{
			idleTimer = new Timer(IDLE_INTERVAL);
			idleTimer.addEventListener(TimerEvent.TIMER,
				idleTimer_timerHandler);
			idleTimer.start();
			
			// Make sure we get all activity
			// in case someone calls stopPropagation().
			addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
			addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
		}
		
		super.addEventListener(type, listener, useCapture, priority, useWeakReference);
	}
	
	/**
	 *  @private
	 */
	mx_internal final function $removeEventListener(type:String, listener:Function,
													useCapture:Boolean = false):void
	{
		super.removeEventListener(type, listener, useCapture);
	}
	
	/**
	 *  @private
	 */
	override public function removeEventListener(type:String, listener:Function,
												 useCapture:Boolean = false):void
	{
		if (hasEventListener("removeEventListener"))
		{
			var request:DynamicEvent = new DynamicEvent("removeEventListener", false, true);
			request.eventType = type;
			request.listener = listener;
			request.useCapture = useCapture;
			if (!dispatchEvent(request))
				return;
		}
		
		// These two events will dispatched to applications in sandboxes.
		if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME)
		{
			if (type == FlexEvent.RENDER)
				type = Event.RENDER;
			else
				type = Event.ENTER_FRAME;
			
			try
			{
				if (stage)
					stage.removeEventListener(type, listener, useCapture);
			}
			catch (error:SecurityError)
			{
			}
			// Remove both listeners in case the system manager was added
			// or removed from the stage after the listener was added.
			super.removeEventListener(type, listener, useCapture);
			
			return;
		}
		
		// When the last listener unregisters for 'idle' events,
		// stop and release the Timer.
		if (type == FlexEvent.IDLE)
		{
			super.removeEventListener(type, listener, useCapture);
			
			if (!hasEventListener(FlexEvent.IDLE) && idleTimer)
			{
				idleTimer.stop();
				idleTimer = null;
				
				removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
				removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			}
		}
		else
		{
			super.removeEventListener(type, listener, useCapture);
		}
		
		if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN 
			|| type == Event.ACTIVATE || type == Event.DEACTIVATE)
		{
			if (!hasEventListener(type))
			{
				// also listen to stage if allowed
				try
				{
					if (stage)
					{
						stage.removeEventListener(type, stageEventHandler, false);
					}
				}
				catch (error:SecurityError)
				{
				}
			}
		}
		
		if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE)
		{
			if (!hasEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE))
			{
				// nobody wants this event any more for now
				try
				{
					if (stage)
					{
						stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
					}
				}
				catch (error:SecurityError)
				{
				}
				// Remove both listeners in case the system manager was added
				// or removed from the stage after the listener was added.
				super.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
			}
		}
	}
	
	//--------------------------------------------------------------------------
	//
	//  Overridden methods: DisplayObjectContainer
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 */
	override public function addChild(child:DisplayObject):DisplayObject
	{
		var addIndex:int = numChildren;
		if (child.parent == this)
			addIndex--;
		
		return addChildAt(child, addIndex);
	}
	
	/**
	 *  @private
	 */
	override public function addChildAt(child:DisplayObject,
										index:int):DisplayObject
	{
		// Adjust the partition indexes before the 
		// "added" event is dispatched.
		noTopMostIndex++;
		
		var oldParent:DisplayObjectContainer = child.parent;
		if (oldParent)
			oldParent.removeChild(child);
		
		return rawChildren_addChildAt(child, applicationIndex + index);
	}
	
	/**
	 *  @private
	 * 
	 * Used by SystemManagerProxy to add a mouse catcher as a child.
	 */ 
	mx_internal final function $addChildAt(child:DisplayObject,
										   index:int):DisplayObject
	{
		return super.addChildAt(child, index);
	}
	
	/**
	 *  @private
	 * 
	 *  Companion to $addChildAt.
	 */
	mx_internal final function $removeChildAt(index:int):DisplayObject
	{
		return super.removeChildAt(index);
	}
	
	
	/**
	 *  @private
	 */
	override public function removeChild(child:DisplayObject):DisplayObject
	{
		// Adjust the partition indexes
		// before the "removed" event is dispatched.
		noTopMostIndex--;
		
		return rawChildren_removeChild(child);
	}
	
	/**
	 *  @private
	 */
	override public function removeChildAt(index:int):DisplayObject
	{
		// Adjust the partition indexes
		// before the "removed" event is dispatched.
		noTopMostIndex--;
		
		return rawChildren_removeChildAt(applicationIndex + index);
	}
	
	/**
	 *  @private
	 */
	override public function getChildAt(index:int):DisplayObject
	{
		return super.getChildAt(applicationIndex + index)
	}
	
	/**
	 *  @private
	 */
	override public function getChildByName(name:String):DisplayObject
	{
		return super.getChildByName(name);
	}
	
	/**
	 *  @private
	 */
	override public function getChildIndex(child:DisplayObject):int
	{
		return super.getChildIndex(child) - applicationIndex;
	}
	
	/**
	 *  @private
	 */
	override public function setChildIndex(child:DisplayObject, newIndex:int):void
	{
		super.setChildIndex(child, applicationIndex + newIndex)
	}
	
	/**
	 *  @private
	 */
	override public function getObjectsUnderPoint(point:Point):Array
	{
		var children:Array = [];
		
		// Get all the children that aren't tooltips and cursors.
		var n:int = topMostIndex;
		for (var i:int = 0; i < n; i++)
		{
			var child:DisplayObject = super.getChildAt(i);
			if (child is DisplayObjectContainer)
			{
				var temp:Array =
					DisplayObjectContainer(child).getObjectsUnderPoint(point);
				
				if (temp)
					children = children.concat(temp);
			}
		}
		
		return children;
	}
	
	/**
	 *  @private
	 */
	override public function contains(child:DisplayObject):Boolean
	{
		if (super.contains(child))
		{
			if (child.parent == this)
			{
				var childIndex:int = super.getChildIndex(child);
				if (childIndex < noTopMostIndex)
					return true;
			}
			else
			{
				for (var i:int = 0; i < noTopMostIndex; i++)
				{
					var myChild:DisplayObject = super.getChildAt(i);
					if (myChild is IRawChildrenContainer)
					{
						if (IRawChildrenContainer(myChild).rawChildren.contains(child))
							return true;
					}
					if (myChild is DisplayObjectContainer)
					{
						if (DisplayObjectContainer(myChild).contains(child))
							return true;
					}
				}
			}
		}
		return false;
	}
	
	//--------------------------------------------------------------------------
	//
	//  Methods: IFlexModuleFactory
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  This method is overridden in the autogenerated subclass.
	 *  It is part of TLF's ISWFContext interface.
	 *  Although this class does not declare that it implements this interface,
	 *  the autogenerated subclass does.
	 */
	public function callInContext(fn:Function, thisArg:Object,
								  argArray:Array, returns:Boolean = true):*
	{
		return undefined;
	}
	
	/**
	 *  A factory method that requests an instance of a
	 *  definition known to the module.
	 * 
	 *  You can provide an optional set of parameters to let building
	 *  factories change what they create based on the
	 *  input. Passing null indicates that the default definition
	 *  is created, if possible. 
	 *
	 *  This method is overridden in the autogenerated subclass.
	 *
	 *  @param params An optional list of arguments. You can pass
	 *  any number of arguments, which are then stored in an Array
	 *  called <code>parameters</code>. 
	 *
	 *  @return An instance of the module, or <code>null</code>.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function create(... params):Object
	{
		var mainClassName:String = info()["mainClassName"];
		
		if (mainClassName == null)
		{
			var url:String = loaderInfo.loaderURL;
			var dot:int = url.lastIndexOf(".");
			var slash:int = url.lastIndexOf("/");
			mainClassName = url.substring(slash + 1, dot);
		}
		
		var mainClass:Class = Class(getDefinitionByName(mainClassName));
		
		return mainClass ? new mainClass() : null;
	}
	
	/**
	 *  @private
	 */
	public function info():Object
	{
		return {};
	}
	
	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 *  Creates an instance of the preloader, adds it as a child, and runs it.
	 *  This is needed by Flash Builder. Do not modify this function.
	 */
	mx_internal function initialize():void
	{
		var runtimeDPIProviderClass:Class = info()["runtimeDPIProvider"] as Class;
		if (runtimeDPIProviderClass)
			Singleton.registerClass("mx.core::RuntimeDPIProvider", runtimeDPIProviderClass);
		
		if (isStageRoot)
		{
			// TODO: Finalize scaling behavior
			Stage_resizeHandler();
			// _width = stage.stageWidth;
			// _height = stage.stageHeight;
		}
		else
		{
			_width = loaderInfo.width;
			_height = loaderInfo.height;
		}
		
		// Create an instance of the preloader and add it to the stage
		preloader = new Preloader();
		
		// Listen for preloader events
		// preloader notifes when it is ok to go to frame2
		preloader.addEventListener(FlexEvent.PRELOADER_DOC_FRAME_READY,
			preloader_preloaderDocFrameReadyHandler);
		// wait for a complete event.  This gives the preloader
		// a chance to load resource modules before
		// everything really gets kicked off
		preloader.addEventListener(Event.COMPLETE,
			preloader_completeHandler);
		// when the app is fully backed remove the preloader and show the app
		preloader.addEventListener(FlexEvent.PRELOADER_DONE,
			preloader_preloaderDoneHandler);
		preloader.addEventListener(RSLEvent.RSL_COMPLETE, 
			preloader_rslCompleteHandler);
		
		// Add the preloader as a child.  Use backing variable because when loaded
		// we redirect public API to parent systemmanager
		if (!_popUpChildren)
		{
			_popUpChildren = new SystemChildrenList(
				this, new QName(mx_internal, "noTopMostIndex"), new QName(mx_internal, "topMostIndex"));
		}
		_popUpChildren.addChild(preloader);
		
		var rsls:Array = info()["rsls"];
		var cdRsls:Array = info()["cdRsls"];
		var usePreloader:Boolean = true;
		if (info()["usePreloader"] != undefined)
			usePreloader = info()["usePreloader"];
		
		var preloaderDisplayClass:Class = info()["preloader"] as Class;
		
		// Put cross-domain RSL information in the RSL list.
		var rslItemList:Array = [];
		var n:int;
		var i:int;
		if (cdRsls && cdRsls.length > 0)
		{
			if (isTopLevel())
				rslDataList = cdRsls;
			else
				rslDataList = LoaderUtil.processRequiredRSLs(this, cdRsls);
			
			var normalizedURL:String = LoaderUtil.normalizeURL(this.loaderInfo);
			var crossDomainRSLItem:Class = Class(getDefinitionByName("mx.core::CrossDomainRSLItem"));
			n = rslDataList.length;
			for (i = 0; i < n; i++)
			{
				var rslWithFailovers:Array = rslDataList[i];
				
				// If crossDomainRSLItem is null, then this is a compiler error. It should not be null.
				var cdNode:Object = new crossDomainRSLItem(rslWithFailovers,
					normalizedURL,
					this);
				rslItemList.push(cdNode);               
			}
		}
		
		// Append RSL information in the RSL list.
		if (rsls != null && rsls.length > 0)
		{
			if (rslDataList == null)
				rslDataList = [];
			
			if (normalizedURL == null)
				normalizedURL = LoaderUtil.normalizeURL(this.loaderInfo);
			
			n = rsls.length;
			for (i = 0; i < n; i++)
			{
				var node:RSLItem = new RSLItem(rsls[i].url, 
					normalizedURL,
					this);
				rslItemList.push(node);
				rslDataList.push([new RSLData(rsls[i].url, null, null, null, 
					false, false, "current")]);
			}
		}
		
		// They can also specify a comma-separated list of URLs
		// for resource modules to be preloaded during frame 1.
		var resourceModuleURLList:String =
			loaderInfo.parameters["resourceModuleURLs"];
		var resourceModuleURLs:Array =
			resourceModuleURLList ? resourceModuleURLList.split(",") : null;
		
		var domain:ApplicationDomain =
			!topLevel && parent is Loader ?
			Loader(parent).contentLoaderInfo.applicationDomain :
			info()["currentDomain"] as ApplicationDomain;
		
		// Initialize the preloader.
		preloader.initialize(
			usePreloader,
			preloaderDisplayClass,
			preloaderBackgroundColor,
			preloaderBackgroundAlpha,
			preloaderBackgroundImage,
			preloaderBackgroundSize,
			isStageRoot ? stage.stageWidth : loaderInfo.width,
			isStageRoot ? stage.stageHeight : loaderInfo.height,
			null,
			null,
			rslItemList,
			resourceModuleURLs,
			domain);
	}
	
	//--------------------------------------------------------------------------
	//
	//  Methods: Support for rawChildren access
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_addChild(child:DisplayObject):DisplayObject
	{
		childManager.addingChild(child);
		
		super.addChild(child);
		
		childManager.childAdded(child); // calls child.createChildren()
		
		return child;
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_addChildAt(child:DisplayObject,
												index:int):DisplayObject
	{
		// preloader goes through here before childManager is set up
		if (childManager) 
			childManager.addingChild(child);
		
		super.addChildAt(child, index);
		
		if (childManager) 
			childManager.childAdded(child); // calls child.createChildren()
		
		return child;
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_removeChild(child:DisplayObject):DisplayObject
	{
		childManager.removingChild(child);
		super.removeChild(child);
		childManager.childRemoved(child);
		
		return child;
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_removeChildAt(index:int):DisplayObject
	{
		var child:DisplayObject = super.getChildAt(index);
		
		childManager.removingChild(child);
		
		super.removeChildAt(index);
		
		childManager.childRemoved(child);
		
		return child;
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_getChildAt(index:int):DisplayObject
	{
		return super.getChildAt(index);
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_getChildByName(name:String):DisplayObject
	{
		return super.getChildByName(name);
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_getChildIndex(child:DisplayObject):int
	{
		return super.getChildIndex(child);
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_setChildIndex(child:DisplayObject, newIndex:int):void
	{
		super.setChildIndex(child, newIndex);
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_getObjectsUnderPoint(pt:Point):Array
	{
		return super.getObjectsUnderPoint(pt);
	}
	
	/**
	 *  @private
	 */
	mx_internal function rawChildren_contains(child:DisplayObject):Boolean
	{
		return super.contains(child);
	}
	
	//--------------------------------------------------------------------------
	//
	//  Methods: Security
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  Calls Security.allowDomain() for the SWF associated with this SystemManager
	 *  plus all the SWFs assocatiated with RSLs preloaded by this SystemManager.
	 * 
	 */  
	public function allowDomain(... domains):void
	{
		// Overridden by compiler generated code.
	}
	
	/**
	 *  Calls Security.allowInsecureDomain() for the SWF associated with this SystemManager
	 *  plus all the SWFs assocatiated with RSLs preloaded by this SystemManager.
	 * 
	 */  
	public function allowInsecureDomain(... domains):void
	{
		// Overridden by compiler generated code.
	}
	
	//--------------------------------------------------------------------------
	//
	//  Methods: Measurement and Layout
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  A convenience method for determining whether to use the
	 *  explicit or measured width.
	 *
	 *  @return A Number that is the <code>explicitWidth</code> if defined,
	 *  or the <code>measuredWidth</code> property if not.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getExplicitOrMeasuredWidth():Number
	{
		return !isNaN(explicitWidth) ? explicitWidth : measuredWidth;
	}
	
	/**
	 *  A convenience method for determining whether to use the
	 *  explicit or measured height.
	 *
	 *  @return A Number that is the <code>explicitHeight</code> if defined,
	 *  or the <code>measuredHeight</code> property if not.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getExplicitOrMeasuredHeight():Number
	{
		return !isNaN(explicitHeight) ? explicitHeight : measuredHeight;
	}
	
	/**
	 *  Calling the <code>move()</code> method
	 *  has no effect as it is directly mapped
	 *  to the application window or the loader.
	 *
	 *  @param x The new x coordinate.
	 *
	 *  @param y The new y coordinate.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function move(x:Number, y:Number):void
	{
	}
	
	/**
	 *  Calling the <code>setActualSize()</code> method
	 *  has no effect if it is directly mapped
	 *  to the application window and if it is the top-level window.
	 *  Otherwise attempts to resize itself, clipping children if needed.
	 *
	 *  @param newWidth The new width.
	 *
	 *  @param newHeight The new height.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function setActualSize(newWidth:Number, newHeight:Number):void
	{
		if (isStageRoot) return;
		
		// mouseCatcher is a mask if not stage root
		// sometimes it is not in sync so we always
		// sync it up
		if (mouseCatcher)
		{
			mouseCatcher.width = newWidth;
			mouseCatcher.height = newHeight;
		}
		
		if (_width != newWidth || _height != newHeight)
		{
			_width = newWidth;
			_height = newHeight;
			
			dispatchEvent(new Event(Event.RESIZE));
		}
	}
	
	
	
	//--------------------------------------------------------------------------
	//
	//  Methods: Other
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getDefinitionByName(name:String):Object
	{
		var domain:ApplicationDomain =
			!topLevel && parent is Loader ?
			Loader(parent).contentLoaderInfo.applicationDomain :
			info()["currentDomain"] as ApplicationDomain;
		
		//trace("SysMgr.getDefinitionByName domain",domain,"currentDomain",info()["currentDomain"]);    
		
		var definition:Object;
		
		if (domain.hasDefinition(name))
		{
			definition = domain.getDefinition(name);
			//trace("SysMgr.getDefinitionByName got definition",definition,"name",name);
		}
		
		return definition;
	}
	
	/**
	 *  Returns the root DisplayObject of the SWF that contains the code
	 *  for the given object.
	 *
	 *  @param object Any Object. 
	 * 
	 *  @return The root DisplayObject
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static function getSWFRoot(object:Object):DisplayObject
	{
		var className:String = getQualifiedClassName(object);
		
		for (var p:* in allSystemManagers)
		{
			var sm:ISystemManager = p as ISystemManager;
			var domain:ApplicationDomain = sm.loaderInfo.applicationDomain;
			try
			{
				var cls:Class = Class(domain.getDefinition(className));
				if (object is cls)
					return sm as DisplayObject;
			}
			catch(e:Error)
			{
			}
		}
		return null;
	}
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function isTopLevel():Boolean
	{
		return topLevel;
	}
	
	/**
	 * @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */ 
	public function isTopLevelRoot():Boolean
	{
		return isStageRoot || isBootstrapRoot;
	}
	
	/**
	 *  Determines if the given DisplayObject is the 
	 *  top-level window.
	 *
	 *  @param object The DisplayObject to test.
	 *
	 *  @return <code>true</code> if the given DisplayObject is the 
	 *  top-level window.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function isTopLevelWindow(object:DisplayObject):Boolean
	{
		return object is IUIComponent &&
			IUIComponent(object) == topLevelWindow;
	}
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function isFontFaceEmbedded(textFormat:TextFormat):Boolean
	{
		var fontName:String = textFormat.font;
		var bold:Boolean = textFormat.bold;
		var italic:Boolean = textFormat.italic;
		
		var fontList:Array = Font.enumerateFonts();
		
		var n:int = fontList.length;
		for (var i:int = 0; i < n; i++)
		{
			var font:Font = Font(fontList[i]);
			if (font.fontName == fontName)
			{
				var style:String = "regular";
				if (bold && italic)
					style = "boldItalic";
				else if (bold)
					style = "bold";
				else if (italic)
					style = "italic";
				
				if (font.fontStyle == style)
					return true;
			}
		}
		
		if (!fontName ||
			!embeddedFontList ||
			!embeddedFontList[fontName])
		{
			return false;
		}
		
		var info:Object = embeddedFontList[fontName];
		
		return !((bold && !info.bold) ||
			(italic && !info.italic) ||
			(!bold && !italic && !info.regular));
	}
	
	/**
	 *  @private
	 *  Makes the mouseCatcher the same size as the stage,
	 *  filling it with transparent pixels.
	 */
	private function resizeMouseCatcher():void
	{
		if (mouseCatcher)
		{
			try
			{
				var g:Graphics = mouseCatcher.graphics;
				var s:Rectangle = screen;
				g.clear();
				g.beginFill(0x000000, 0);
				g.drawRect(0, 0, s.width, s.height);
				g.endFill();
			}
			catch (e:SecurityError)
			{
				// trace("resizeMouseCatcher: ignoring security error " + e);
			}
		}
	}
	
	//--------------------------------------------------------------------------
	//
	//  Event handlers
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 */
	private function initHandler(event:Event):void
	{
//		CONFIG::performanceInstrumentation
//		{
//			var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
//			perfUtil.markTime("SystemManager.initHandler().start");
//		}
		
		// we can still be the top level root if we can access our
		// parent and get a positive response to the query or
		// or there is not a listener for the new application event
		// that SWFLoader always adds. 
		if (!isStageRoot)
		{
			if (root.loaderInfo.parentAllowsChild)
			{
				try
				{
					if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true)) ||
						// use string literal to avoid link dependency on SWFBridgeEvent.BRIDGE_NEW_APPLICATION
						!root.loaderInfo.sharedEvents.hasEventListener("bridgeNewApplication"))
						isBootstrapRoot = true;
				}
				catch (e:Error)
				{
				}
			}
		}
		
		allSystemManagers[this] = this.loaderInfo.url;
		root.loaderInfo.removeEventListener(Event.INIT, initHandler);
		
		if (!SystemManagerGlobals.info)
			SystemManagerGlobals.info = info();
		if (!SystemManagerGlobals.parameters)
			SystemManagerGlobals.parameters = loaderInfo.parameters;
		
		var docFrame:int = (totalFrames == 1)? 0 : 1;
		addEventListener(Event.ENTER_FRAME, docFrameListener);
		
		/*
		addFrameScript(docFrame, docFrameHandler);
		for (var f:int = docFrame + 1; f < totalFrames; ++f)
		{
		addFrameScript(f, extraFrameHandler);
		}
		*/
		
		initialize();
		
//		CONFIG::performanceInstrumentation
//		{
//			perfUtil.markTime("SystemManager.initHandler().end");
//		}
	}
	
	private function docFrameListener(event:Event):void
	{
		if (currentFrame == 2)
		{
			removeEventListener(Event.ENTER_FRAME, docFrameListener);
			if (totalFrames > 2)
				addEventListener(Event.ENTER_FRAME, extraFrameListener);
			
			docFrameHandler();
		}
	}
	
	private function extraFrameListener(event:Event):void
	{
		if (lastFrame == currentFrame)
			return;
		
		lastFrame = currentFrame;
		
		if (currentFrame + 1 > totalFrames)
			removeEventListener(Event.ENTER_FRAME, extraFrameListener);
		
		extraFrameHandler();
	}
	
	/**
	 *  @private
	 *  Once the swf has been fully downloaded,
	 *  advance the playhead to the next frame.
	 *  This will cause the framescript to run, which runs frameEndHandler().
	 */
	private function preloader_preloaderDocFrameReadyHandler(event:Event):void
	{
		// Advance the next frame
		preloader.removeEventListener(FlexEvent.PRELOADER_DOC_FRAME_READY,
			preloader_preloaderDocFrameReadyHandler);
		
		deferredNextFrame();
	}
	
	/**
	 *  @private
	 *  Remove the preloader and add the application as a child.
	 */
	private function preloader_preloaderDoneHandler(event:Event):void
	{
		var app:IUIComponent = topLevelWindow;
		
		// Once the preloader dispatches the PRELOADER_DONE event, remove the preloader
		// and add the application as the child
		preloader.removeEventListener(FlexEvent.PRELOADER_DONE,
			preloader_preloaderDoneHandler);
		preloader.removeEventListener(RSLEvent.RSL_COMPLETE, 
			preloader_rslCompleteHandler);
		
		_popUpChildren.removeChild(preloader);
		preloader = null;
		
		// Add the mouseCatcher as child 0.
		mouseCatcher = new FlexSprite();
		mouseCatcher.name = "mouseCatcher";
		// Must use addChildAt because a creationComplete handler can create a
		// dialog and insert it at 0.
		noTopMostIndex++;
		super.addChildAt(mouseCatcher, 0);  
		resizeMouseCatcher();
		if (!topLevel)
		{
			mouseCatcher.visible = false;
			mask = mouseCatcher;
		}
		
		// Add the application as child 1.
		noTopMostIndex++;
		super.addChildAt(DisplayObject(app), 1);
		
//		CONFIG::performanceInstrumentation
//		{
//			var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
//			perfUtil.markTime("APPLICATION_COMPLETE");
//			perfUtil.finishSampling("Application Startup");
//		}
		
		// Dispatch the applicationComplete event from the Application
		// and then agaom from the SystemManager
		// (so that loading apps know we're done).
		app.dispatchEvent(new FlexEvent(FlexEvent.APPLICATION_COMPLETE));
		dispatchEvent(new FlexEvent(FlexEvent.APPLICATION_COMPLETE));
	}
	
	/**
	 *  @private
	 *  The preloader has completed loading an RSL.
	 */
	private function preloader_rslCompleteHandler(event:RSLEvent):void
	{
		if (!event.isResourceModule && event.loaderInfo)
		{
			var rsl:Vector.<RSLData> = Vector.<RSLData>(rslDataList[event.rslIndex]);
			var moduleFactory:IFlexModuleFactory = this;
			if (rsl && rsl[0].moduleFactory)
				moduleFactory = rsl[0].moduleFactory; 
			
			if (moduleFactory == this)
				preloadedRSLs[event.loaderInfo] =  rsl;
			else
				moduleFactory.addPreloadedRSL(event.loaderInfo, rsl);
		}
	}
	
	/**
	 *  @private
	 *  This is attached as the framescript at the end of frame 2.
	 *  When this function is called, we know that the application
	 *  class has been defined and read in by the Player.
	 */
	mx_internal function docFrameHandler(event:Event = null):void
	{
		
		if (readyForKickOff)
			kickOff();
	}
	
	/**
	 *  @private
	 *  kick off if we're ready
	 */
	mx_internal function preloader_completeHandler(event:Event):void
	{
		preloader.removeEventListener(Event.COMPLETE,
			preloader_completeHandler);
		readyForKickOff = true;
		if (currentFrame >= 2)
			kickOff();
	}   
	
	/**
	 *  @private
	 *  kick off 
	 */
	mx_internal function kickOff():void
	{
		// already been here
		if (document)
			return;
		
//		CONFIG::performanceInstrumentation
//		{
//			var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance();
//			perfUtil.markTime("SystemManager.kickOff().start");
//		}
		
		if (!isTopLevel())
			SystemManagerGlobals.topLevelSystemManagers[0].
				// dispatch a FocusEvent so we can pass ourselves along
				dispatchEvent(new FocusEvent(FlexEvent.NEW_CHILD_APPLICATION, false, false, this));
		
		// Generated code will bring in EmbeddedFontRegistry
		Singleton.registerClass("mx.core::IEmbeddedFontRegistry",
			Class(getDefinitionByName("mx.core::EmbeddedFontRegistry")));
		
		Singleton.registerClass("mx.styles::IStyleManager",
			Class(getDefinitionByName("mx.styles::StyleManagerImpl")));
		
		Singleton.registerClass("mx.styles::IStyleManager2",
			Class(getDefinitionByName("mx.styles::StyleManagerImpl")));
		
		// Register other singleton classes.
		// Note: getDefinitionByName() will return null
		// if the class can't be found.
		
		Singleton.registerClass("mx.managers::IBrowserManager",
			Class(getDefinitionByName("mx.managers::BrowserManagerImpl")));
		
		Singleton.registerClass("mx.managers::ICursorManager",
			Class(getDefinitionByName("mx.managers::CursorManagerImpl")));
		
		Singleton.registerClass("mx.managers::IHistoryManager",
			Class(getDefinitionByName("mx.managers::HistoryManagerImpl")));
		
		Singleton.registerClass("mx.managers::ILayoutManager",
			Class(getDefinitionByName("mx.managers::LayoutManager")));
		
		Singleton.registerClass("mx.managers::IPopUpManager",
			Class(getDefinitionByName("mx.managers::PopUpManagerImpl")));
		
		Singleton.registerClass("mx.managers::IToolTipManager2",
			Class(getDefinitionByName("mx.managers::ToolTipManagerImpl")));
		
		var dragManagerClass:Class = null;
		
		// Make this call to create a new instance of the DragManager singleton. 
		// Try to link in the NativeDragManager first. This will allow the  
		// application to receive NativeDragEvents that originate from the
		// desktop.  If it can't be found, then we're 
		// not in AIR, and it can't be linked in, so we should just work off of 
		// the regular Flex DragManager.
		var dmInfo:Object = info()["useNativeDragManager"];
		
		var useNative:Boolean = dmInfo == null ? true : String(dmInfo) == "true";
		
		if (useNative)
			dragManagerClass = Class(getDefinitionByName("mx.managers::NativeDragManagerImpl"));
		
		if (dragManagerClass == null)
			dragManagerClass = Class(getDefinitionByName("mx.managers::DragManagerImpl"));
		
		Singleton.registerClass("mx.managers::IDragManager", dragManagerClass);
		
		Singleton.registerClass("mx.core::ITextFieldFactory", 
			Class(getDefinitionByName("mx.core::TextFieldFactory")));
		
		var mixinList:Array = info()["mixins"];
		if (mixinList && mixinList.length > 0)
		{
			var n:int = mixinList.length;
			for (var i:int = 0; i < n; ++i)
			{
//				CONFIG::performanceInstrumentation
//				{
//					var token:int = perfUtil.markStart();
//				}
				
				// trace("initializing mixin " + mixinList[i]);
				var c:Class = Class(getDefinitionByName(mixinList[i]));
				c["init"](this);
				
//				CONFIG::performanceInstrumentation
//				{
//					perfUtil.markEnd(mixinList[i], token);
//				}
			}
		}
		
		c = Singleton.getClass("mx.managers::IActiveWindowManager");
		if (c)
		{
			registerImplementation("mx.managers::IActiveWindowManager", new c(this));
		}
		
		// depends on having IActiveWindowManager installed first
		c = Singleton.getClass("mx.managers::IMarshalSystemManager");
		if (c)
		{
			registerImplementation("mx.managers::IMarshalSystemManager", new c(this));
		}
		
//		CONFIG::performanceInstrumentation
//		{
//			// Finish here, since initializeTopLevelWidnow is instrumented separately???
//			perfUtil.markTime("SystemManager.kickOff().end");
//		}
		
		initializeTopLevelWindow(null);
		
		deferredNextFrame();
	}
	
	/**
	 *  @private
	 *  The Flash Player dispatches KeyboardEvents with cancelable=false. 
	 *  We'd like to be able to use the preventDefault() method on some
	 *  KeyBoard events to record the fact that they've been handled. 
	 *  This method stops propagation of the original event and redispatches
	 *  the new one from the original event's target.
	 * 
	 *  We're only handling a small subset of keyboard events, to 
	 *  avoid unnecessary copying.   Most of events in the subset are
	 *  handled by both Scroller and by Spark classes like TextArea or
	 *  or List that include a Scroller in their skin. 
	 */
	private function keyDownHandler(e:KeyboardEvent):void
	{
		if (!e.cancelable)
		{
			switch (e.keyCode)
			{
			case Keyboard.UP:
			case Keyboard.DOWN:
			case Keyboard.PAGE_UP:
			case Keyboard.PAGE_DOWN:
			case Keyboard.HOME:
			case Keyboard.END:
			case Keyboard.LEFT:
			case Keyboard.RIGHT:
			case Keyboard.ENTER:
			{
				e.stopImmediatePropagation();
				var cancelableEvent:KeyboardEvent =
					new KeyboardEvent(e.type, e.bubbles, true, e.charCode, e.keyCode, 
						e.keyLocation, e.ctrlKey, e.altKey, e.shiftKey)              
				e.target.dispatchEvent(cancelableEvent);
			}
			}
		}
	}
	
	/**
	 *  @private 
	 *  Similar to keyDownHandler above.  We want to re-dispatch 
	 *  mouse events that are cancellable.  Currently we are only doing 
	 *  this for a few mouse events and not all of them (MOUSE_WHEEL and 
	 *  MOUSE_DOWN).
	 */
	private function mouseEventHandler(e:MouseEvent):void
	{
		if (!e.cancelable)
		{
			e.stopImmediatePropagation();
			var cancelableEvent:MouseEvent = null;
			if ("clickCount" in e)
			{
				// AIR MouseEvent. We need to use a constructor so we can
				// pass in clickCount because it is a read-only property.
				var mouseEventClass:Class = MouseEvent;
				
				cancelableEvent = new mouseEventClass(e.type, e.bubbles, true, e.localX,
					e.localY, e.relatedObject, e.ctrlKey, e.altKey,
					e.shiftKey, e.buttonDown, e.delta, 
					e["commandKey"], e["controlKey"], e["clickCount"]);
			}
			else
			{
				cancelableEvent = new MouseEvent(e.type, e.bubbles, true, e.localX, 
					e.localY, e.relatedObject, e.ctrlKey, e.altKey,
					e.shiftKey, e.buttonDown, e.delta);
			}
			
			e.target.dispatchEvent(cancelableEvent);               
		}
	}
	
	private function extraFrameHandler(event:Event = null):void
	{
		var frameList:Object = info()["frames"];
		
		if (frameList && frameList[currentLabel])
		{
			var c:Class = Class(getDefinitionByName(frameList[currentLabel]));
			c["frame"](this);
		}
		
		deferredNextFrame();
	}
	
	/**
	 *  @private
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	private function nextFrameTimerHandler(event:TimerEvent):void
	{
		if (currentFrame + 1 <= framesLoaded)
		{
			nextFrame();
			nextFrameTimer.removeEventListener(TimerEvent.TIMER, nextFrameTimerHandler);
			// stop the timer
			nextFrameTimer.reset();
		}
	}
	
	
	/**
	 *  @private
	 *  Instantiates an instance of the top level window
	 *  and adds it as a child of the SystemManager.
	 */
	private function initializeTopLevelWindow(event:Event):void
	{
//		// This listener is intended to run before any other KeyboardEvent listeners
//		// so that it can redispatch a cancelable=true copy of the event. 
//		if (getSandboxRoot() == this)
//		{
//			addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, true, 1000);
//			addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, true, 1000);
//			addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, true, 1000);
//		}
//		if (isTopLevelRoot() && stage)
//		{
//			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, false, 1000);
//			stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, false, 1000);
//			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, false, 1000);
//		}
//		
		// Parent may be null if in another sandbox and don't have
		// access to our parent.  Add a check for this case.
		if (!parent && parentAllowsChild)
			return;
		
		if (!topLevel)
		{
			// We are not top-level and don't have a parent. This can happen
			// when the application has already been unloaded by the time
			// we get to this point.
			if (!parent)
				return;
			
			var obj:DisplayObjectContainer = parent.parent;
			
			// if there is no grandparent at this point, we might have been removed and
			// are about to be killed so just bail.  Other code that runs after
			// this point expects us to be grandparented.  Another scenario
			// is that someone loaded us but not into a parented loader, but that
			// is not allowed.
			if (!obj)
				return;
			
			while (obj)
			{
				if (obj is IUIComponent)
				{
					var sm:ISystemManager = IUIComponent(obj).systemManager;
					if (sm && !sm.isTopLevel())
						sm = sm.topLevelSystemManager;
					
					_topLevelSystemManager = sm;
					break;
				}
				obj = obj.parent;
			}
		}
		
		if (isTopLevelRoot() && stage)
			stage.addEventListener(Event.RESIZE, Stage_resizeHandler, false, 0, true);
		else if (topLevel && stage)
		{
			// listen to resizes on the sandbox root
			var sandboxRoot:DisplayObject = getSandboxRoot();
			if (sandboxRoot != this)
				sandboxRoot.addEventListener(Event.RESIZE, Stage_resizeHandler, false, 0, true);
		}
		
		var w:Number;
		var h:Number;
		
		if (isStageRoot && stage)
		{
			// stageWidth/stageHeight may have changed between initialize() and now,
			// so refresh our _width and _height here. 
			
			// TODO: finalize scaling behavior
			Stage_resizeHandler();
			//_width = stage.stageWidth;
			//_height = stage.stageHeight;
			
			// Detect and account for special case where our stage in some 
			// contexts has not actually been initialized fully, as is the 
			// case with IE if the window is fully obscured upon loading.
			if (_width == 0 && _height == 0 && 
				loaderInfo.width != _width && 
				loaderInfo.height != _height)
			{
				_width = loaderInfo.width;
				_height = loaderInfo.height;
			}
			w = _width;
			h = _height;
		}   
		else
		{
			w = loaderInfo.width;
			h = loaderInfo.height;
		}
		
		childManager.initializeTopLevelWindow(w, h);
	}
	
	/**
	 *  listen for creationComplete" on the application
	 *  if you want to perform any logic
	 *  when the application has finished initializing itself.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	private function appCreationCompleteHandler(event:FlexEvent):void
	{
		invalidateParentSizeAndDisplayList();
	}
	
	/**
	 *  Attempts to notify the parent SWFLoader that the
	 *  Application's size has changed.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 10
	 *  @playerversion AIR 1.5
	 *  @productversion Flex 4
	 */
	public function invalidateParentSizeAndDisplayList():void
	{
		if (!topLevel && parent)
		{
			var obj:DisplayObjectContainer = parent.parent;
			while (obj)
			{
				if (obj is IInvalidating)
				{
					IInvalidating(obj).invalidateSize();
					IInvalidating(obj).invalidateDisplayList();
					return;
				}
				obj = obj.parent;
			}
		}
		
		// re-dispatch from here so MarshallPlan mixins can see it
		dispatchEvent(new Event("invalidateParentSizeAndDisplayList"));
	}
	
	/**
	 *  @private
	 *  Keep track of the size and position of the stage.
	 */
	private function Stage_resizeHandler(event:Event = null):void
	{   
		if (isDispatchingResizeEvent)
			return;
		
		var w:Number = 0;
		var h:Number = 0;
		var m:Number;
		var n:Number;
		
		try
		{
			m = loaderInfo.width;
			n = loaderInfo.height;
		}
		catch (error:Error)
		{
			// Error #2099: The loading object is not sufficiently loaded to provide this information.
			// We get this error because an old Event.RESIZE listener with a weak reference
			// is being called but the SWF has been unloaded.
			if (!_screen)
				_screen = new Rectangle();
			
			return; 
		}
		
		var align:String = StageAlign.TOP_LEFT;
		
		// If we don't have access to the stage, then use the size of 
		// the sandbox root and align to StageAlign.TOP_LEFT.                        
		try 
		{
			if (stage)
			{
				w = stage.stageWidth;
				h = stage.stageHeight;
				align = stage.align;
			}
		}
		catch (error:SecurityError)
		{
			if (hasEventListener("getScreen"))
			{
				dispatchEvent(new Event("getScreen"));
				if (_screen)
				{
					w = _screen.width;
					h = _screen.height;
				}
			}
		}
		
		var x:Number = (m - w) / 2;
		var y:Number = (n - h) / 2;
		
		if (align == StageAlign.TOP)
		{
			y = 0;
		}
		else if (align == StageAlign.BOTTOM)
		{
			y = n - h;
		}
		else if (align == StageAlign.LEFT)
		{
			x = 0;
		}
		else if (align == StageAlign.RIGHT)
		{
			x = m - w;
		}
		else if (align == StageAlign.TOP_LEFT || align == "LT") // player bug 125020
		{
			y = 0;
			x = 0;
		}
		else if (align == StageAlign.TOP_RIGHT)
		{
			y = 0;
			x = m - w;
		}
		else if (align == StageAlign.BOTTOM_LEFT)
		{
			y = n - h;
			x = 0;
		}
		else if (align == StageAlign.BOTTOM_RIGHT)
		{
			y = n - h;
			x = m - w;
		}
		
		if (!_screen)
			_screen = new Rectangle();
		_screen.x = x;
		_screen.y = y;
		_screen.width = w;
		_screen.height = h;
		
		if (isStageRoot)
		{
			var scale:Number = densityScale;
			
			root.scaleX = root.scaleY = scale;
			_width = stage.stageWidth / scale;
			_height = stage.stageHeight / scale;
			
			// Update the screen
			_screen.x /= scale;
			_screen.y /= scale;
			_screen.width /= scale;
			_screen.height /= scale;
		}
		
		if (event)
		{
			resizeMouseCatcher();
			isDispatchingResizeEvent = true;
			dispatchEvent(event);
			isDispatchingResizeEvent = false;
		}
	}
	
	/**
	 *  @private
	 * 
	 * Get the index of an object in a given child list.
	 * 
	 * @return index of f in childList, -1 if f is not in childList.
	 */ 
	private static function getChildListIndex(childList:IChildList, f:Object):int
	{
		var index:int = -1;
		try
		{
			index = childList.getChildIndex(DisplayObject(f)); 
		}
		catch (e:ArgumentError)
		{
			// index has been preset to -1 so just continue.    
		}
		
		return index; 
	}
	
	/**
	 *  @private
	 *  Track mouse moves in order to determine idle
	 */
	private function mouseMoveHandler(event:MouseEvent):void
	{
		// Reset the idle counter.
		idleCounter = 0;
	}
	
	/**
	 *  @private
	 *  Track mouse moves in order to determine idle.
	 */
	private function mouseUpHandler(event:MouseEvent):void
	{
		// Reset the idle counter.
		idleCounter = 0;
	}
	
	/**
	 *  @private
	 *  Called every IDLE_INTERVAL after the first listener
	 *  registers for 'idle' events.
	 *  After IDLE_THRESHOLD goes by without any user activity,
	 *  we dispatch an 'idle' event.
	 */
	private function idleTimer_timerHandler(event:TimerEvent):void
	{
		idleCounter++;
		
		if (idleCounter * IDLE_INTERVAL > IDLE_THRESHOLD)
			dispatchEvent(new FlexEvent(FlexEvent.IDLE));
	}
	
	
	
	// fake out mouseX/mouseY
	mx_internal var _mouseX:*;
	mx_internal var _mouseY:*;
	
	
	/**
	 *  @private
	 */
	override public function get mouseX():Number
	{
		if (_mouseX === undefined)
			return super.mouseX;
		return _mouseX;
	}
	
	/**
	 *  @private
	 */
	override public function get mouseY():Number
	{
		if (_mouseY === undefined)
			return super.mouseY;
		return _mouseY;
	}
	
	
	private function getTopLevelSystemManager(parent:DisplayObject):ISystemManager
	{
		var localRoot:DisplayObjectContainer = DisplayObjectContainer(parent.root);
		var sm:ISystemManager;
		
		// If the parent isn't rooted yet,
		// Or the root is the stage (which is the case in a second AIR window)
		// use the global system manager instance.
		if ((!localRoot || localRoot is Stage) && parent is IUIComponent)
			localRoot = DisplayObjectContainer(IUIComponent(parent).systemManager);
		if (localRoot is ISystemManager)
		{
			sm = ISystemManager(localRoot);
			if (!sm.isTopLevel())
				sm = sm.topLevelSystemManager;
		}
		
		return sm;
	}
	
	/**
	 * Override parent property to handle the case where the parent is in
	 * a differnt sandbox. If the parent is in the same sandbox it is returned.
	 * If the parent is in a diffent sandbox, then null is returned.
	 * 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */ 
	override public function get parent():DisplayObjectContainer
	{
		try
		{
			return super.parent;
		}   
		catch (e:SecurityError) 
		{
			// trace("parent: ignoring security error");
		}
		
		return null;
	}
	
	
	/**
	 *  Go up the parent chain to get the top level system manager.
	 * 
	 *  Returns <code>null</code> if not on the display list or we don't have
	 *  access to the top-level system manager.
	 *  
	 *  @return The root system manager.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getTopLevelRoot():DisplayObject
	{
		// work our say up the parent chain to the root. This way we
		// don't have to rely on this object being added to the stage.
		try
		{
			var sm:ISystemManager = this;
			if (sm.topLevelSystemManager)
				sm = sm.topLevelSystemManager;
			var parent:DisplayObject = DisplayObject(sm).parent;
			var lastParent:DisplayObject = DisplayObject(sm);
			while (parent)
			{
				if (parent is Stage)
					return lastParent;
				lastParent = parent; 
				parent = parent.parent;             
			}
		}
		catch (error:SecurityError)
		{
		}       
		
		return null;
	}
	
	/**
	 *  Go up the parent chain to get the top level system manager in this 
	 *  SecurityDomain.
	 * 
	 *  @return The root system manager in this SecurityDomain.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getSandboxRoot():DisplayObject
	{
		// work our say up the parent chain to the root. This way we
		// don't have to rely on this object being added to the stage.
		var sm:ISystemManager = this;
		
		try
		{
			if (sm.topLevelSystemManager)
				sm = sm.topLevelSystemManager;
			var parent:DisplayObject = DisplayObject(sm).parent;
			if (parent is Stage)
				return DisplayObject(sm);
			// test to see if parent is a Bootstrap
			if (parent && !parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true)))
				return this;
			var lastParent:DisplayObject = this;
			while (parent)
			{
				if (parent is Stage)
					return lastParent;
				// test to see if parent is a Bootstrap
				if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true)))
					return lastParent;
				
				// Test if the childAllowsParent so we know there is mutual trust between
				// the sandbox root and this sm.
				// The parentAllowsChild is taken care of by the player because it returns null
				// for the parent if we do not have access.
				if (parent is Loader)
				{
					var loader:Loader = Loader(parent);
					var loaderInfo:LoaderInfo = loader.contentLoaderInfo;
					if (!loaderInfo.childAllowsParent)
						return loaderInfo.content;
				}
				
				// If an object is listening for system manager request we assume it is a sandbox
				// root. If not, don't assign lastParent to this parent because it may be a
				// non-Flex application. We only want Flex apps to be returned as sandbox roots.
				// use constant to avoid link dependency on InterManagerRequest.SYSTEM_MANAGER_REQUEST
				
				if (parent.hasEventListener("systemManagerRequest" 
				))
					lastParent = parent; 
				parent = parent.parent;             
			}
		}
		catch (error:Error)
		{
			// Either we don't have security access to a parent or
			// the swf is unloaded and loaderInfo.childAllowsParent is throwing Error #2099.
		}       
		
		return lastParent != null ? lastParent : DisplayObject(sm);
	}
	
	/**
	 * @private
	 *  A map of fully-qualified interface names,
	 *  such as "mx.managers::IPopUpManager",
	 *  to instances,
	 */
	private var implMap:Object = {};
	
	/**
	 * @private
	 *  Adds an interface-name-to-implementation-class mapping to the registry,
	 *  if a class hasn't already been registered for the specified interface.
	 *  The class must implement a getInstance() method which returns
	 *  its singleton instance.
	 */
	public function registerImplementation(interfaceName:String,
										   impl:Object):void
	{
		var c:Object = implMap[interfaceName];
		if (!c)
			implMap[interfaceName] = impl;
	}
	
	/**
	 * @private
	 *  Returns the singleton instance of the implementation class
	 *  that was registered for the specified interface,
	 *  by looking up the class in the registry
	 *  and calling its getInstance() method.
	 * 
	 *  This method should not be called at static initialization time,
	 *  because the factory class may not have called registerClass() yet.
	 */
	public function getImplementation(interfaceName:String):Object
	{
		var c:Object = implMap[interfaceName];
		return c;
	}
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getVisibleApplicationRect(bounds:Rectangle = null, skipToSandboxRoot:Boolean = false):Rectangle
	{
		if (hasEventListener("getVisibleApplicationRect"))
		{
			var request:Request = new Request("getVisibleApplicationRect", false, true);
			request.value = { bounds: bounds, skipToSandboxRoot: skipToSandboxRoot };
			if (!dispatchEvent(request)) 
				return Rectangle(request.value);
		}
		
		if (skipToSandboxRoot && !topLevel)
			return topLevelSystemManager.getVisibleApplicationRect(bounds, skipToSandboxRoot);
		
		if (!bounds)
		{
			bounds = getBounds(DisplayObject(this));
			
			var sandboxRoot:DisplayObject = getSandboxRoot();
			var s:Rectangle = screen.clone();
			s.topLeft = sandboxRoot.localToGlobal(screen.topLeft);
			s.bottomRight = sandboxRoot.localToGlobal(screen.bottomRight);
			var pt:Point = new Point(Math.max(0, bounds.x), Math.max(0, bounds.y));
			pt = localToGlobal(pt);
			bounds.x = pt.x;
			bounds.y = pt.y;
			bounds.width = s.width;
			bounds.height = s.height;
		}
		
		if (!topLevel)
		{
			var obj:DisplayObjectContainer = parent.parent;
			
			if ("getVisibleApplicationRect" in obj)
			{
				var visibleRect:Rectangle = obj["getVisibleApplicationRect"](true);
				bounds = bounds.intersection(visibleRect);
			}
		}
		return bounds;
	}
	
	/**
	 *  @inheritDoc
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function deployMouseShields(deploy:Boolean):void
	{
		if (hasEventListener("deployMouseShields"))
		{
			var dynamicEvent:DynamicEvent = new DynamicEvent("deployMouseShields");
			dynamicEvent.deploy = deploy;
			dispatchEvent(dynamicEvent);
		}
	}
	
	/**
	 *  @private
	 *  dispatch certain stage events from sandbox root
	 */
	private function stageEventHandler(event:Event):void
	{
		if (event.target is Stage && mouseCatcher)
		{
			// need to fix up the coordinate space before re-dispatching the mouse event  
			// to put it in the same coordinate space as the mouseCatcher since the 
			// mouseCatcher may be scaled while outside of the stage, we are not
			if (event is MouseEvent)
			{
				var mouseEvent:MouseEvent = MouseEvent(event);
				var stagePoint:Point = new Point(mouseEvent.stageX, mouseEvent.stageY);
				var mouesCatcherLocalPoint:Point = mouseCatcher.globalToLocal(stagePoint);
				mouseEvent.localX = mouesCatcherLocalPoint.x;
				mouseEvent.localY = mouesCatcherLocalPoint.y;
			}
			
			// dispatch them from mouseCatcher so capture phase listeners on 
			// systemManager will work
			mouseCatcher.dispatchEvent(event);
		}
	}
	
	/**
	 *  @private
	 *  convert MOUSE_LEAVE to MOUSE_UP_SOMEWHERE
	 */
	private function mouseLeaveHandler(event:Event):void
	{
		dispatchEvent(new SandboxMouseEvent(SandboxMouseEvent.MOUSE_UP_SOMEWHERE));
	}
	
}

}
